#include "boot.h"
#include "variable.h"

uint16_t binPacketTotal;			// bin文件总包数
uint16_t binPacketIndex;			// bin文件当前包序号
uint32_t binVersion;					// bin文件版本号
uint32_t localVersion;				// 当前固件版本号
uint16_t appFlag=UPDATA_START;				// APP固件状态  START开始更新或者没有固件

typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;

#if   (defined ( __CC_ARM ))
  __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
  __no_init __IO uint32_t VectorTable[48];
#elif defined   (  __GNUC__  )
  __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
#elif defined ( __TASKING__ )
  __IO uint32_t VectorTable[48] __at(0x20000000);
#endif




// 重新映射中断向量表
void IAPAPP_Init(uint32_t add)
{
	for(uint8_t i = 0; i < 48; i++)
  {
    VectorTable[i] = *(__IO uint32_t*)(add + (i<<2));
  }
  /* Enable the SYSCFG peripheral clock*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 
  /* Remap SRAM at 0x00000000 */
  //SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
	SYSCFG->CFGR1 |= 0x03;
}


// 跳转sp指针
void IAP_APP_Jump (uint32_t add)
{
	IAPAPP_Init(add);
	uint32_t SpInitVal; //要跳转到程序的SP初值.
	uint32_t JumpAddr;  //要跳转到程序的地址，即要跳转到程序的入口
	void (*pFun)(void); //定义一个函数指针.用于指向APP程序入口
	RCC_DeInit(); //关闭外设
	SpInitVal = *(uint32_t *)add;//IAP_ADDR IAP的栈顶地址（0x08000000）
	//跳转到APP时 APP_ADDR AAP的栈顶地址（如：0x08003800）
	JumpAddr = *(uint32_t *)( add + 4); //设置复位中断向量（如上面流程分析）
	__set_MSP(SpInitVal); //设置SP.，堆栈栈顶地址
	pFun = (void (*)(void))JumpAddr; //生成跳转函数.将复位中断向量地址做为函数指针
	(*pFun) (); //执行函数，实现跳转.不再返回.
}


